<?php
/**
 * Created by PhpStorm.
 * User: nightelf
 * Date: 2020/8/18
 * Time: 17:38
 */

namespace App\Http\Model;


use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ApprovalModel
{
    const TABLE = "approval";

    public function insert($data)
    {
        return DB::table(self::TABLE)->insertGetId($data);
    }

    public function info(array $data)
    {
        $result = DB::table(self::TABLE)->where($data)->first();
        return empty($result) ? [] : get_object_vars($result);
    }

    public function update(array $where, array $data)
    {
        return DB::table(self::TABLE)->where($where)->update($data);
    }

    /**
     * @param array $data
     * @return mixed
     */
    public function lists(array $data)
    {
        $limit = config('yucheng.limit');
        $start = 0;
        if (!empty($data['length'])) {
            $limit = $data['length'];
        }
        if (!empty($data['page'])) {
            $start = ($data['page'] - 1) * $limit;
        }

        return DB::table(self::TABLE)
            ->leftJoin('project as p', 'p.id', '=', self::TABLE . '.projectId')
            ->where(function ($query) use ($data) {
                if (!empty($data['projectId'])) {
                    $query->where(self::TABLE . '.projectId', $data['projectId']);
                }
                if (!empty($data['adminId'])) {
                    $query->where(self::TABLE . '.adminId', $data['adminId']);
                }
                if (!empty($data['status'])) {
                    $query->where(self::TABLE . '.status', $data['status']);
                }
                $query->where('startTime', '>=', $data['month'] . '-01');
            })
            ->offset($start)->limit($limit)
            ->select(self::TABLE . '.*', 'p.name')
            ->get()->toArray();
    }

    /**
     * @param array $data
     * @return mixed
     */
    public function countLists(array $data)
    {
        return DB::table(self::TABLE)
            ->leftJoin('project as p', 'p.id', '=', self::TABLE . '.projectId')
            ->where(function ($query) use ($data) {
                if (!empty($data['projectId'])) {
                    $query->where(self::TABLE . '.projectId', $data['projectId']);
                }
                if (!empty($data['adminId'])) {
                    $query->where(self::TABLE . '.adminId', $data['adminId']);
                }
                if (!empty($data['status'])) {
                    $query->where(self::TABLE . '.status', $data['status']);
                }
                $query->where('startTime', '>=', $data['month'] . '-01');
            })
            ->count();
    }

    public function checkApproval(array $data)
    {
        $result = DB::table(self::TABLE)
            ->where(function ($query) use ($data) {
                if (!empty($data['projectId'])) {
                    $query->where('projectId', $data['projectId']);
                }
                if (!empty($data['startTime'])) {
                    $query->where('endTime', '>', $data['startTime']);
                }
            })
            ->first();
        if (empty($result)) {
            return true;
        } else {
            return false;
        }
    }

    public function initiateApplication(array $param)
    {
        DB::beginTransaction();
        try {
            $projectModel = new ProjectModel();
            $noticeModel = new NoticeModel();

            //建立每个审批的流程审批明细，用于后面记录审批结果
            if ($param['projectId'] == 0) {
                $projectLists = $projectModel->selectLists(['status' => 1]);
            } else {
                $p = new \stdClass();
                $p->id = $param['projectId'];
                $projectLists[] = $p;
            }
            foreach ($projectLists as $p) {
                //验证每个项目的账目审批时间是否和以前的账目审批时间有重合的地方
                $minProcess = DB::table('approval_node')->min('process');
                $approval = [
                    'projectId' => $p->id,
                    'startTime' => $param['startTime'] . ' 00:00:00',
                    'endTime' => $param['endTime'] . ' 23:59:59',
                    'adminId' => $param['adminId'],
                    'process' => $minProcess,
                    'createTime' => date('Y-m-d H:i:s'),
                ];
                $approvalId = $this->insert($approval);
                $order = 0;
                //获取审批事项所有流程节点
                $nodeList = DB::table('approval_node')->orderBy('process')->get()->toArray();

                foreach ($nodeList as $n) {
                    //获取每个节点参与审批的角色
                    $roleList = DB::table('approval_node_role')->where('nodeId', $n->id)->get()->toArray();
                    foreach ($roleList as $r) {
                        $result = [];
                        if ($r->workmanAssignment == 1) {
                            $result['workmanAssignment'] = 0;
                        }
                        if ($r->workmanAccounts == 1) {
                            $result['workmanAccounts'] = 0;
                        }
                        if ($r->handymanAccounts == 1) {
                            $result['handymanAccounts'] = 0;
                        }
                        if ($r->attendance == 1) {
                            $result['attendance'] = 0;
                        }
                        if ($r->loan == 1) {
                            $result['loan'] = 0;
                        }
                        if ($r->living == 1) {
                            $result['living'] = 0;
                        }
                        if ($r->supplier == 1) {
                            $result['supplier'] = 0;
                        }
                        if ($r->warehouse == 1) {
                            $result['warehouse'] = 0;
                        }
                        $process = [
                            'approvalId' => $approvalId,
                            'nodeId' => $n->id,
                            'roleId' => $r->roleId,
                            'process' => $n->process,
                            'order' => $order,
                            'result' => json_encode($result),
                        ];
                        DB::table('approval_process')->insert($process);
                    }
                    $order++;
                }

                $notice = [
                    "projectId" => $param['projectId'],
                    "title" => "账目审核通知",
                    "content" => "<p>" . $param['startTime'] . "至" . $param['endTime'] . "期间的账目已开启审核，请各位工长尽快录入账目，并提交审核</p>",
                    "createTime" => date("Y-m-d H:i:s"),
                    "updateTime" => date("Y-m-d H:i:s"),
                    "isTop" => 1,
                    "adminId" => 0,
                    "isShow" => 1,
                ];
                $noticeModel->insert($notice);
            }

            DB::commit();
        } catch (\Exception $e) {
            Log::info($e->getMessage() . ' in ' . $e->getFile() . '(' . $e->getLine() . ')');
            DB::rollback();
            return false;
        }
    }

    public function submission(array $param)
    {
        DB::beginTransaction();
        try {
            $approval = $this->info(['id' => $param['approvalId']]);

            $adminRoleModel = new AdminRoleModel();
            $adminRole = $adminRoleModel->getAdminRole($param['adminId']);

            $approvalProcessModel = new ApprovalProcessModel();
            $processInfo = $approvalProcessModel->info(['roleId' => $adminRole['roleId'], 'approvalId' => $param['approvalId'],'roleId'=>$adminRole['roleId']]);
            $result = json_decode($processInfo['result'], true);

            //变更账目状态
            foreach ($result as $k => $v) {
                if ($k == 'workmanAssignment') {
                    DB::table('workman_assignment')
                        ->where(function ($query) use ($param, $approval) {
                            $query->where(['adminId'=>$param['adminId']]);
                                $query->whereBetween('completeTime', [$approval['startTime'], $approval['endTime']]);
                            })->where('batch','>',0)
                        ->update(['status' => 1]);
                    $result[$k] = 1;
                } elseif ($k == 'workmanAccounts') {
                    DB::table('workman_accounts')
                        ->where(function ($query) use ($param, $approval) {
                            $query->where(['adminId'=>$param['adminId']]);
                                $query->whereBetween('separateTime', [$approval['startTime'], $approval['endTime']]);
                            })->where('batch','>',0)
                        ->update(['status' => 1]);
                    $result[$k] = 1;
                } elseif ($k == 'handymanAccounts') {
                    DB::table('handyman_accounts')
                        ->where(function ($query) use ($param, $approval) {
//                            $query->where(['adminId'=>$param['adminId']]);
                                $query->whereBetween('separateTime', [$approval['startTime'], $approval['endTime']]);
                            })
                        ->update(['status' => 1]);
                    $result[$k] = 1;
                } elseif ($k == 'attendance') {
                    DB::table('attendance')
                        ->where(function ($query) use ($param, $approval) {
                            $query->whereBetween('day', [$approval['startTime'], $approval['endTime']]);
                        })
                        ->update(['status' => 1]);
                    $result[$k] = 1;
                } else {
                    $result[$k] = 1;
                }
            }

            //变更审批进度节点的状态
            if (!in_array(0, $result)) {
                $process = DB::table('approval_process')
                    ->where(['approvalId' => $param['approvalId'], 'roleId' => $adminRole['roleId']])
                    ->orderBy('order')
                    ->first();
                DB::table('approval_process')->where(['approvalId' => $param['approvalId'], 'roleId' => $adminRole['roleId'],'id'=>$process->id])
                    ->update(['status' => 1, 'adminId' => $param['adminId'], 'updateTime' => date('Y-m-d H:i:s'),'result'=>json_encode($result)]);
            }

            //变更审批事项进度
            //查看同级审批节点内的所有角色是否都审批完成
            $notApproved = DB::table('approval_process')->where(['approvalId' => $param['approvalId'], 'process' => $processInfo['process'], 'status' => 0])->first();
            if (empty($notApproved)) {
                //同级审批节点内的所有角色都审批完成
                //查看下一节点的process
                $newProcess = DB::table('approval_process')->where(['approvalId' => $param['approvalId'], 'status' => 0])->min('process');
                if (empty($newProcess)) {
                    //下一节点的process为空，则更新审批事项为完成状态
                    $this->update(['id' => $param['approvalId']], ['status' => 3]);
                } else {
                    //存在下一节点的process，则更新审批事项的process为下一节点
                    $this->update(['id' => $param['approvalId']], ['process' => $newProcess,'status'=>1]);
                }

            }
            DB::commit();
            return true;
        } catch (\Exception $e) {
            Log::info($e->getMessage() . ' in ' . $e->getFile() . '(' . $e->getLine() . ')');
            DB::rollback();
            return false;
        }
    }

    public function submit(array $param)
    {
        DB::beginTransaction();
        try {
//            $approval = $this->info(['id' => $param['approvalId']]);
            $adminRoleModel = new AdminRoleModel();
            $adminRole = $adminRoleModel->getAdminRole($param['adminId']);

            $approvalProcessModel = new ApprovalProcessModel();
            $processInfo = $approvalProcessModel->info(['roleId' => $adminRole['roleId'], 'approvalId' => $param['approvalId'],'roleId'=>$adminRole['roleId']]);
            $result = json_decode($processInfo['result'], true);

            // 控制项目的供应商变更状态
            $approval = (new ApprovalModel())->info(['id'=>$param['approvalId']]);
            DB::table('supplier_orders')->where('projectId' ,$approval['projectId'])
                ->whereBetween('deliveryTime',[$approval['startTime'],$approval['endTime']])
                ->update(['status' => 2]);

            //变更账目状态
            foreach ($result as $k => $v) {
                if ($k == 'workmanAssignment') {
                    $result[$k] = 1;
                } elseif ($k == 'workmanAccounts') {
                    $result[$k] = 1;
                } elseif ($k == 'handymanAccounts') {
                    $result[$k] = 1;
                } elseif ($k == 'attendance') {
                    $result[$k] = 1;
                } else {
                    $result[$k] = 1;
                }
            }

            //变更审批进度节点的状态
            if (!in_array(0, $result)) {
                DB::table('approval_process')
                    ->where(['approvalId' => $param['approvalId'], 'roleId' => $adminRole['roleId'],'status' =>0])
                    ->update(['status' => 1, 'adminId' => $param['adminId'], 'updateTime' => date('Y-m-d H:i:s'),'result'=>json_encode($result)]);
            }

            //变更审批事项进度
            //查看同级审批节点内的所有角色是否都审批完成
            $notApproved = DB::table('approval_process')->where(['approvalId' => $param['approvalId'], 'process' => $processInfo['process'], 'status' => 0])->first();
            if (empty($notApproved)) {
                //同级审批节点内的所有角色都审批完成
                //查看下一节点的process
                $newProcess = DB::table('approval_process')->where(['approvalId' => $param['approvalId'], 'status' => 0])->min('process');
                if (empty($newProcess)) {
                    //下一节点的process为空，则更新审批事项为完成状态
                    $this->update(['id' => $param['approvalId']], ['status' => 3]);
                } else {
                    //存在下一节点的process，则更新审批事项的process为下一节点
                    $this->update(['id' => $param['approvalId']], ['process' => $newProcess,'status'=>2]);
                }
            }
            DB::commit();
            return true;
        } catch (\Exception $e) {
            Log::info($e->getMessage() . ' in ' . $e->getFile() . '(' . $e->getLine() . ')');
            DB::rollback();
            return false;
        }
    }
}